/*
 *--------------------------------------------------------------------------
 *   File Name:	reboot.S
 * 
 * Description:	none
 * 
 * 
 *      Author:	Zhao Yanbai [zhaoyanbai@126.com]
 * 
 *     Version:	1.0
 * Create Date: Mon Nov 10 15:58:46 2008
 * Last Update: Tue Feb 10 22:39:24 2009
 * 
 *--------------------------------------------------------------------------
 */
#define ASM
#include"multiboot.h"
#define	KRNLADDR	0xC0000000
.global	_start
.extern CheckKernel
.extern SetupKernel
.extern	KernelEntry
.extern	krnl_end	# 在scripts/link.ld的文件中
.text
.code32
.align 32
_start:
	jmp	PMEntry

	# Multiboot Header
	# Align 32 bits boundary
	.align	4
	# Magic
	.long	MULTIBOOT_HEADER_MAGIC
	# Flags
	.long	MULTIBOOT_HEADER_FLAGS
	# Checksum
	.long	-(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)

PMEntry:
	# Reset EFLAGS
	pushl	$0
	popf

	# Load GDT's Information To GDTR
	lgdt	GDTR-KRNLADDR

	mov	$0x10,%dx
	mov	%dx,%ds
	mov	%dx,%es
	mov	%dx,%ss
	mov	%dx,%fs
	mov	%dx,%gs

	movl	$(stack + MULTIBOOT_STACK_SIZE - KRNLADDR), %esp


	# Save Multiboot Infomation...
	pushl	%eax
	addl	$KRNLADDR,%ebx
	pushl	%ebx

	# Setup Page 
	movl	$krnl_end-KRNLADDR,%ebx
	movl	%ebx,%edi
	movl	$1024,%ecx
	xorl	%eax,%eax
	cld
	rep
	stosl

	movl	%ebx,%edi
	movl	%ebx,%eax
	movl	%ebx,%ecx
	addl	$0x1007,%eax
	addl	$0x2007,%ecx
	movl	%eax, 0000(%edi)
	movl	%ecx, 0004(%edi)
	movl	%eax, 3072(%edi)
	movl	%ecx, 3076(%edi)

	movl	%ebx,%edi
	addl	$0x1000,%edi
	movl	$2048,%ecx
	movl	$0x07,%eax
	cld
1:
	stosl
	addl	$0x1000,%eax
	loop	1b

	movl	%ebx,%cr3

	movl	%cr0,%eax
	orl	$0x80000000,%eax
	movl	%eax,%cr0


	jmp	2f
2:

	ljmp	$0x08,$Label
Label:
	call	CheckKernel
	addl	$8,%esp
	call	SetupKernel
	call	KernelEntry
Die:	jmp	Die

.align 32
BootGDT:
EMPT:	.long	0x00000000,0x00000000
Code:	.long	0x0000FFFF,0x00CF9B00
Data:	.long	0x0000FFFF,0x00CF9300
BootGDTEnd:
GDTR:
	GDTRLimit:	.word	BootGDTEnd-BootGDT
	GDTRBase:	.long	BootGDT-KRNLADDR
	.comm	stack, MULTIBOOT_STACK_SIZE
